#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
视力数据计算服务 - 完整修复版本
"""

from flask import current_app
from datetime import datetime, date, timedelta, time as datetime_time
from typing import Dict, List, Optional, Tuple, Any
import pandas as pd
from sqlalchemy import and_, or_, func
from sqlalchemy.exc import IntegrityError
from backend.infrastructure.database import db
from backend.models.vision import VisionRecord
from backend.models.student import Student
from backend.models.student_extension import StudentExtension
from backend.models.intervention import InterventionRecord
from backend.config.config_manager import ConfigManager

# 初始化配置管理器
config_manager = ConfigManager()
VISION_CALCULATION_CONFIG = config_manager.get_vision_calculation_config()
VISION_LEVEL_THRESHOLDS = config_manager.get_vision_level_thresholds()
EFFECT_ASSESSMENT_THRESHOLDS = config_manager.get_effect_assessment_thresholds()

# 已删除重复的SE计算函数，统一使用calculate_se_unified

# 已删除错误的calculate_vision_level_by_age函数
# 统一使用determine_vision_level函数，修复SE=-0.5边界判断错误

def calculate_comprehensive_vision_level(left_level: str, right_level: str) -> str:
    """计算综合视力等级 - 取两眼最差"""
    try:
        level_severity = {
            "假性近视": 1,
            "其他": 2,
            "临床前期近视": 3,
            "轻度近视": 4,
            "中度近视": 5,
            "高度近视": 6
        }
        
        left_severity = level_severity.get(left_level, 2)
        right_severity = level_severity.get(right_level, 2)
        max_severity = max(left_severity, right_severity)
        
        for level, severity in level_severity.items():
            if severity == max_severity:
                return level
        
        return "其他"
        
    except Exception as e:
        print(f"计算综合视力等级失败: {e}")
        return "其他"

def extract_birthday_from_id_card(id_card: str) -> Optional[date]:
    """从身份证号提取出生日期"""
    try:
        if not id_card or len(id_card) != 18:
            return None
        
        birth_str = id_card[6:14]
        year = int(birth_str[0:4])
        month = int(birth_str[4:6])
        day = int(birth_str[6:8])
        
        return date(year, month, day)
        
    except (ValueError, IndexError):
        return None

def calculate_birthday_from_age(age: Optional[int], data_year: Optional[str]) -> Optional[date]:
    """根据年龄和数据年份反算出生年份"""
    try:
        if age is None or data_year is None:
            return None
        
        birth_year = int(data_year) - age
        return date(birth_year, 1, 1)
        
    except (ValueError, TypeError):
        return None

def ensure_student_birthday_completeness(student, age_from_excel: Optional[int] = None, data_year: Optional[str] = None) -> bool:
    """确保学生出生日期完整性"""
    try:
        if student.birthday:
            return True
        
        if student.id_card:
            birthday = extract_birthday_from_id_card(student.id_card)
            if birthday:
                student.birthday = birthday
                print(f"从身份证号推算出生日期: {birthday}")
                return True
        
        if age_from_excel is not None and data_year is not None:
            birthday = calculate_birthday_from_age(age_from_excel, data_year)
            if birthday:
                student.birthday = birthday
                print(f"根据年龄{age_from_excel}和数据年份{data_year}反算出生年份: {birthday}")
                return True
        
        print("无法推算出生日期，该学生将跳过年龄相关统计")
        return False
        
    except Exception as e:
        print(f"补充学生出生日期失败: {e}")
        return False

# 统一的SE计算函数 - 配置驱动
def calculate_se_unified(sphere, cylinder):
    """统一的SE计算函数 - 配置驱动"""
    if sphere is None or cylinder is None:
        null_handling = VISION_CALCULATION_CONFIG.get("se_calculation", {}).get("null_handling", "return_none")
        return None if null_handling == "return_none" else 0
    
    # 使用配置的计算公式
    formula = VISION_CALCULATION_CONFIG.get("se_calculation", {}).get("formula", "sphere + cylinder / 2")
    if formula == "sphere + cylinder / 2":
        result = sphere + (cylinder / 2)
    else:
        # 支持扩展其他计算公式
        result = sphere + (cylinder / 2)
    
    # 使用配置的舍入精度
    rounding_digits = VISION_CALCULATION_CONFIG.get("se_calculation", {}).get("rounding_digits", 2)
    return round(result, rounding_digits)

def calculate_vision_metrics(record, force_recalculate=False):
    """计算视力记录的所有预计算字段"""
    try:
        if hasattr(record, 'calculation_status') and record.calculation_status == "completed" and not force_recalculate:
            return True
        
        # SE计算和赋值
        if record.right_sphere is not None and record.right_cylinder is not None:
            record.right_se = calculate_se_unified(record.right_sphere, record.right_cylinder)
        
        if record.left_sphere is not None and record.left_cylinder is not None:
            record.left_se = calculate_se_unified(record.left_sphere, record.left_cylinder)
        
        # 散瞳SE计算
        if record.right_dilated_sphere is not None and record.right_dilated_cylinder is not None:
            record.right_dilated_se = calculate_se_unified(record.right_dilated_sphere, record.right_dilated_cylinder)
        
        if record.left_dilated_sphere is not None and record.left_dilated_cylinder is not None:
            record.left_dilated_se = calculate_se_unified(record.left_dilated_sphere, record.left_dilated_cylinder)
        
        # 计算年龄 - 修复：处理日期字段类型问题
        if hasattr(record, 'student') and record.student and record.student.birthday and record.measure_date:
            try:
                # 确保measure_date是日期对象
                measure_date = record.measure_date
                if isinstance(measure_date, str):
                    from datetime import datetime
                    if 'T' in measure_date:
                        measure_date = datetime.fromisoformat(measure_date.replace('Z', '+00:00')).date()
                    else:
                        measure_date = datetime.strptime(measure_date, '%Y-%m-%d').date()
                    record.measure_date = measure_date
                
                # 确保birthday是日期对象
                birthday = record.student.birthday
                if isinstance(birthday, str):
                    from datetime import datetime
                    birthday = datetime.strptime(birthday, '%Y-%m-%d').date()
                    record.student.birthday = birthday
                
                age_at_measure = measure_date.year - birthday.year
                if (measure_date.month, measure_date.day) < (birthday.month, birthday.day):
                    age_at_measure -= 1
                record.age_at_measure = age_at_measure 
            except Exception as e:
                print(f"计算年龄时出错: {e}")
                record.age_at_measure = calculate_age_at_measure(record.student_id, record.measure_date)
        else:
            record.age_at_measure = calculate_age_at_measure(record.student_id, record.measure_date)
        
        # 设置数据年份 - 修复：处理日期字段类型问题
        if record.measure_date:
            try:
                # 确保measure_date是日期对象
                measure_date = record.measure_date
                if isinstance(measure_date, str):
                    from datetime import datetime
                    if 'T' in measure_date:
                        measure_date = datetime.fromisoformat(measure_date.replace('Z', '+00:00')).date()
                    else:
                        measure_date = datetime.strptime(measure_date, '%Y-%m-%d').date()
                    record.measure_date = measure_date
                
                record.data_year = str(measure_date.year)
            except Exception as e:
                print(f"设置数据年份时出错: {e}")
                record.data_year = "2025"  # 默认值
        
        # 判定视力等级
        if record.left_se is not None:
            record.left_vision_level = determine_vision_level(
                record.left_se, 
                record.left_dilated_se, 
                record.age_at_measure
            )
        
        if record.right_se is not None:
            record.right_vision_level = determine_vision_level(
                record.right_se, 
                record.right_dilated_se, 
                record.age_at_measure
            )
        
        # 计算综合视力等级
        if record.left_vision_level and record.right_vision_level:
            record.comprehensive_vision_level = calculate_comprehensive_vision_level(
                record.left_vision_level, 
                record.right_vision_level
            )
            record.vision_level = record.comprehensive_vision_level
        elif record.left_vision_level:
            record.comprehensive_vision_level = record.left_vision_level
            record.vision_level = record.left_vision_level
        elif record.right_vision_level:
            record.comprehensive_vision_level = record.right_vision_level
            record.vision_level = record.right_vision_level
        
        # 标记计算完成
        if hasattr(record, 'calculation_status'):
            record.calculation_status = "completed"
            record.last_calculated_at = datetime.now()
        
        # 计算基线对比
        if not record.is_baseline:
            try:
                calculate_baseline_comparisons(record)
            except Exception as e:
                print(f"基线对比计算失败: {e}")
        
        return True
        
    except Exception as e:
        if hasattr(record, 'calculation_status'):
            record.calculation_status = "failed"
            record.calculation_error = str(e)
        
        if current_app:
            current_app.logger.error(f"视力记录计算失败 (ID: {record.id}): {str(e)}")
        else:        
            print(f"视力记录计算失败 (ID: {record.id}): {str(e)}")
        return False

# 别名，向后兼容
calculate_record = calculate_vision_metrics

def process_student_vision_data(row_data, student_id):
    """处理学生视力数据"""
    try:
        from backend.models.vision import VisionRecord
        from backend.constants import normalize_grade, normalize_class
        
        vision_records = []
        
        # 标准化年级班级数据
        if '年级' in row_data:
            row_data['年级'] = normalize_grade(row_data['年级'])
        if '班级' in row_data:
            row_data['班级'] = normalize_class(row_data['班级'])
        
        # 解析干预时间
        intervention_times = []
        for i in range(1, 17):
            col_name = f'第{i}次干预'
            if col_name in row_data and row_data[col_name]:
                intervention_times.append({
                    'date': parse_simple_date(row_data[col_name]),
                    'time': None
                })
        
        if not intervention_times:
            print(f"学生 {student_id} 没有有效的干预时间数据")
            return []
        
        # 第一条记录：基线数据
        baseline_record = VisionRecord(
            student_id=student_id,
            measure_date=intervention_times[0]['date'],
            measure_time=intervention_times[0].get('time'),
            measure_type="基线数据",
            measurer="数据导入",
            is_baseline=True,
            calculation_status="pending"
        )
        
        # 基线字段映射
        baseline_fields = [
            ('right_eye_naked', '右眼-裸眼视力'),
            ('left_eye_naked', '左眼-裸眼视力'),
            ('right_eye_corrected', '右眼-矫正视力'),
            ('left_eye_corrected', '左眼-矫正视力'),
            ('right_sphere', '右眼屈光-球镜'),
            ('right_cylinder', '右眼屈光-柱镜'),
            ('right_axis', '右眼屈光-轴位'),
            ('left_sphere', '左眼屈光-球镜'),
            ('left_cylinder', '左眼屈光-柱镜'),
            ('left_axis', '左眼屈光-轴位'),
        ]
        
        # 填充基线数据
        for db_field, excel_column in baseline_fields:
            if excel_column in row_data:
                value = safe_float_or_null(row_data[excel_column])
                setattr(baseline_record, db_field, value)
                print(f"✅基线映射: {excel_column} -> {db_field} = {value}")
        
        vision_records.append(baseline_record)
        
        # 第二条记录：随访数据
        followup_record = VisionRecord(
            student_id=student_id,
            measure_date=intervention_times[-1]['date'],
            measure_time=intervention_times[-1].get('time'),
            measure_type="随访测量",
            measurer="数据导入",
            is_baseline=False,
            calculation_status="pending"
        )
        
        # 随访字段映射
        followup_fields = [
            ('right_eye_naked', '右眼-干预-裸眼视力'),
            ('left_eye_naked', '左眼-干预-裸眼视力'),
            ('right_sphere', '右眼屈光-干预-球镜'),
            ('right_cylinder', '右眼屈光-干预-柱镜'),
            ('right_axis', '右眼屈光-干预-轴位'),
            ('left_sphere', '左眼屈光-干预-球镜'),
            ('left_cylinder', '左眼屈光-干预-柱镜'),
            ('left_axis', '左眼屈光-轴位'),
        ]
        
        # 填充随访数据
        for db_field, excel_column in followup_fields:
            if excel_column in row_data:
                value = safe_float_or_null(row_data[excel_column])
                setattr(followup_record, db_field, value)
                print(f"✅随访映射: {excel_column} -> {db_field} = {value}")
        
        vision_records.append(followup_record)
        
        print(f"✅学生 {student_id} 生成基线和随访记录各1条")
        return vision_records
        
    except Exception as e:
        print(f"处理学生 {student_id} 视力数据失败: {e}")
        return []

def safe_float_or_null(value):
    """安全转换为浮点数或NULL"""
    if value is None or value == '' or str(value).strip() == '':
        return None
    try:
        return float(value)
    except (ValueError, TypeError):
        return None

def parse_simple_date(date_value):
    """解析简单日期格式"""
    try:
        if not date_value:
            return None
        
        date_str = str(date_value).strip()
        
        if '-' in date_str:
            if date_str.count('-') == 2:
                year, month, day = date_str.split('-')
                return date(int(year), int(month), int(day))
        elif '/' in date_str:
            if date_str.count('/') == 2:
                year, month, day = date_str.split('/')
                return date(int(year), int(month), int(day))
        elif '年' in date_str and '月' in date_str and '日' in date_str:
            date_str = date_str.replace('年', '-').replace('月', '-').replace('日', '')
            year, month, day = date_str.split('-')
            return date(int(year), int(month), int(day))
        
        return None
        
    except (ValueError, TypeError):
        return None

def find_baseline(student_id):
    """查找学生的基线记录"""
    from backend.models.vision import VisionRecord
    
    return VisionRecord.query.filter_by(
        student_id=student_id,
        is_baseline=True
    ).order_by(VisionRecord.measure_date.asc()).first()

def calculate_age_at_measure(student_id, measure_date):
    """计算测量时的实际年龄 - 修复：处理日期字段类型问题"""
    from backend.models.student import Student
    
    from backend.infrastructure.database import db
    student = db.session.get(Student, student_id)
    if not student or not student.birthday or not measure_date:
        return None
    
    try:
        # 确保measure_date是日期对象
        if isinstance(measure_date, str):
            from datetime import datetime
            if 'T' in measure_date:
                measure_date = datetime.fromisoformat(measure_date.replace('Z', '+00:00')).date()
            else:
                measure_date = datetime.strptime(measure_date, '%Y-%m-%d').date()
        
        # 确保birthday是日期对象
        birthday = student.birthday
        if isinstance(birthday, str):
            from datetime import datetime
            birthday = datetime.strptime(birthday, '%Y-%m-%d').date()
        
        age = measure_date.year - birthday.year
        if measure_date.month < birthday.month or \
           (measure_date.month == birthday.month and measure_date.day < birthday.day):
            age -= 1
        
        return age
    except Exception as e:
        print(f"计算年龄时出错: {e}")
        return None
    except Exception as e:
        print(f"计算年龄时出错: {e}")
        return None

# 在determine_vision_level函数中使用配置
def determine_vision_level(se_value, dilated_se_value, age_at_measure):
    """配置驱动的视力等级判定"""
    if se_value is None:
        return None
    
    thresholds = VISION_LEVEL_THRESHOLDS
    
    # 假性近视判定 - 使用配置的阈值
    if dilated_se_value is not None:
        threshold = thresholds["假性近视"]["dilated_se_threshold"]
        if abs(dilated_se_value) < threshold and abs(se_value) >= threshold:
            return "假性近视"
    
    # 近视度数分级 - 修正边界值判断逻辑
    # 业务标准：SE < -6.0D为高度近视
    if se_value < thresholds["高度近视"]["se_max"]:
        return "高度近视"
    # 业务标准：-6.0D ≤ SE < -3.0D为中度近视  
    elif thresholds["中度近视"]["se_min"] <= se_value < thresholds["中度近视"]["se_max"]:
        return "中度近视"
    # 业务标准：-3.0D ≤ SE < -0.5D为轻度近视
    elif thresholds["轻度近视"]["se_min"] <= se_value < thresholds["轻度近视"]["se_max"]:
        return "轻度近视"
    
    # 临床前期近视 - 使用配置的年龄分层
    if age_at_measure is not None:
        pre_myopia = thresholds["临床前期近视"]["age_groups"]
        if 6 <= age_at_measure <= 9:
            age_config = pre_myopia["6-9"]
            if age_config["se_min"] < se_value <= age_config["se_max"]:
                return "临床前期近视"
        elif 10 <= age_at_measure <= 12:
            age_config = pre_myopia["10-12"]
            if age_config["se_min"] < se_value <= age_config["se_max"]:
                return "临床前期近视"
    
    return "正常"

def get_worse_vision_level(left_level, right_level):
    """获取两眼中更严重的视力等级"""
    severity_order = {
        "高度近视": 5,
        "中度近视": 4,
        "轻度近视": 3,
        "临床前期近视": 2,
        "假性近视": 1,
        "正常": 0
    }
    
    left_severity = severity_order.get(left_level, 0)
    right_severity = severity_order.get(right_level, 0)
    
    if left_severity >= right_severity:
        return left_level
    else:
        return right_level

# 在calculate_effect_assessment函数中使用配置
def calculate_effect_assessment(vision_record):
    """配置驱动的效果评估"""
    thresholds = EFFECT_ASSESSMENT_THRESHOLDS
    
    # 视力效果评估 - 使用配置的阈值
    if hasattr(vision_record, 'baseline_left_naked_change') and vision_record.baseline_left_naked_change is not None:
        change = vision_record.baseline_left_naked_change
        if change > thresholds["vision_change"]["improve"]:
            vision_record.baseline_left_vision_effect = "上升"
        elif change < thresholds["vision_change"]["decline"]:
            vision_record.baseline_left_vision_effect = "下降"
        else:
            vision_record.baseline_left_vision_effect = "维持"
    
    # 右眼视力效果评估
    if hasattr(vision_record, 'baseline_right_naked_change') and vision_record.baseline_right_naked_change is not None:
        change = vision_record.baseline_right_naked_change
        if change > thresholds["vision_change"]["improve"]:
            vision_record.baseline_right_vision_effect = "上升"
        elif change < thresholds["vision_change"]["decline"]:
            vision_record.baseline_right_vision_effect = "下降"
        else:
            vision_record.baseline_right_vision_effect = "维持"
    
    # SE效果评估 - 使用配置的阈值
    if hasattr(vision_record, 'baseline_left_se_change') and vision_record.baseline_left_se_change is not None:
        change = vision_record.baseline_left_se_change
        if change > thresholds["se_change"]["improve"]:
            vision_record.baseline_left_se_effect = "向好"
        elif change < thresholds["se_change"]["decline"]:
            vision_record.baseline_left_se_effect = "向差"
        else:
            vision_record.baseline_left_se_effect = "维持"
    
    # 右眼SE效果评估
    if hasattr(vision_record, 'baseline_right_se_change') and vision_record.baseline_right_se_change is not None:
        change = vision_record.baseline_right_se_change
        if change > thresholds["se_change"]["improve"]:
            vision_record.baseline_right_se_effect = "向好"
        elif change < thresholds["se_change"]["decline"]:
            vision_record.baseline_right_se_effect = "向差"
        else:
            vision_record.baseline_right_se_effect = "维持"

    # 球镜效果评估
    if hasattr(vision_record, 'baseline_left_sphere_change') and vision_record.baseline_left_sphere_change is not None:
        change = vision_record.baseline_left_sphere_change
        if change > thresholds["sphere_change"]["improve"]:
            vision_record.baseline_left_sphere_effect = "向好"
        elif change < thresholds["sphere_change"]["decline"]:
            vision_record.baseline_left_sphere_effect = "向差"
        else:
            vision_record.baseline_left_sphere_effect = "维持"
    
    if hasattr(vision_record, 'baseline_right_sphere_change') and vision_record.baseline_right_sphere_change is not None:
        change = vision_record.baseline_right_sphere_change
        if change > thresholds["sphere_change"]["improve"]:
            vision_record.baseline_right_sphere_effect = "向好"
        elif change < thresholds["sphere_change"]["decline"]:
            vision_record.baseline_right_sphere_effect = "向差"
        else:
            vision_record.baseline_right_sphere_effect = "维持"

    # 散光变化评估
    if hasattr(vision_record, 'baseline_left_cylinder_change') and vision_record.baseline_left_cylinder_change is not None:
        change = abs(vision_record.baseline_left_cylinder_change)
        if change >= thresholds["cylinder_change"]["significant"]:
            vision_record.baseline_left_cylinder_effect = "显著变化"
        else:
            vision_record.baseline_left_cylinder_effect = "稳定"
    
    if hasattr(vision_record, 'baseline_right_cylinder_change') and vision_record.baseline_right_cylinder_change is not None:
        change = abs(vision_record.baseline_right_cylinder_change)
        if change >= thresholds["cylinder_change"]["significant"]:
            vision_record.baseline_right_cylinder_effect = "显著变化"
        else:
            vision_record.baseline_right_cylinder_effect = "稳定"

    # 轴位变化评估
    if hasattr(vision_record, 'baseline_left_axis_change') and vision_record.baseline_left_axis_change is not None:
        change = abs(vision_record.baseline_left_axis_change)
        if change >= thresholds["axis_change"]["significant"]:
            vision_record.baseline_left_axis_effect = "显著变化"
        else:
            vision_record.baseline_left_axis_effect = "稳定"
    
    if hasattr(vision_record, 'baseline_right_axis_change') and vision_record.baseline_right_axis_change is not None:
        change = abs(vision_record.baseline_right_axis_change)
        if change >= thresholds["axis_change"]["significant"]:
            vision_record.baseline_right_axis_effect = "显著变化"
        else:
            vision_record.baseline_right_axis_effect = "稳定"

def calculate_baseline_comparisons(vision_record):
    """计算基线对比变化值和效果评估"""
    if vision_record.is_baseline:
        return
    
    baseline = find_baseline(vision_record.student_id)
    if not baseline:
        return
    
    # 计算变化值
    if vision_record.left_eye_naked is not None and baseline.left_eye_naked is not None:
        vision_record.baseline_left_naked_change = vision_record.left_eye_naked - baseline.left_eye_naked
    
    if vision_record.right_eye_naked is not None and baseline.right_eye_naked is not None:
        vision_record.baseline_right_naked_change = vision_record.right_eye_naked - baseline.right_eye_naked
    
    # 计算球镜变化
    if vision_record.left_sphere is not None and baseline.left_sphere is not None:
        vision_record.baseline_left_sphere_change = vision_record.left_sphere - baseline.left_sphere
    
    if vision_record.right_sphere is not None and baseline.right_sphere is not None:
        vision_record.baseline_right_sphere_change = vision_record.right_sphere - baseline.right_sphere
    
    # 计算SE变化
    if vision_record.left_se is not None and baseline.left_se is not None:
        vision_record.baseline_left_se_change = vision_record.left_se - baseline.left_se
    
    if vision_record.right_se is not None and baseline.right_se is not None:
        vision_record.baseline_right_se_change = vision_record.right_se - baseline.right_se
    
    # 其他变化值计算
    if vision_record.left_cylinder is not None and baseline.left_cylinder is not None:
        vision_record.baseline_left_cylinder_change = vision_record.left_cylinder - baseline.left_cylinder
    
    if vision_record.right_cylinder is not None and baseline.right_cylinder is not None:
        vision_record.baseline_right_cylinder_change = vision_record.right_cylinder - baseline.right_cylinder
    
    if vision_record.left_axis is not None and baseline.left_axis is not None:
        vision_record.baseline_left_axis_change = vision_record.left_axis - baseline.left_axis
    
    if vision_record.right_axis is not None and baseline.right_axis is not None:
        vision_record.baseline_right_axis_change = vision_record.right_axis - baseline.right_axis
    
    # 🎯 关键修复：添加效果评估调用
    calculate_effect_assessment(vision_record)
    
    print(f"学生{vision_record.student_id}：基线对比计算完成")

def recalculate_baseline_comparisons(student_id):
    """重新计算某学生的所有基线对比字段"""
    from backend.models.vision import VisionRecord
    
    # 获取该学生的所有非基线记录
    non_baseline_records = VisionRecord.query.filter_by(
        student_id=student_id,
        is_baseline=False
    ).all()
    
    # 重新计算每条记录的基线对比
    for record in non_baseline_records:
        calculate_baseline_comparisons(record)

def set_baseline(student_id, vision_record_id):
    """设置学生的基线记录"""
    from backend.models.vision import VisionRecord
    from backend.infrastructure.database import db
    
    try:
        # 1. 清除该学生的所有基线标记
        VisionRecord.query.filter_by(
            student_id=student_id,
            is_baseline=True
        ).update({'is_baseline': False})
        
        # 2. 设置新的基线记录
        from backend.infrastructure.database import db
        target_record = db.session.get(VisionRecord, vision_record_id)
        if target_record:
            target_record.is_baseline = True
            
        db.session.commit()
        
        # 3. 重新计算基线对比
        recalculate_baseline_comparisons(student_id)
        
        return True
        
    except Exception as e:
        db.session.rollback()
        print(f"设置基线记录失败: {e}")
        return False

def calculate_intervention_effects(student_id):
    """计算学生的干预效果评估"""
    from backend.models.vision import VisionRecord
    
    baseline = find_baseline(student_id)
    latest = VisionRecord.query.filter_by(student_id=student_id).order_by(
        VisionRecord.measure_date.desc()
    ).first()
    
    if not baseline or not latest or baseline.id == latest.id:
        return None
    
    effects = {}
    if baseline.left_eye_naked and latest.left_eye_naked:
        left_vision_change = latest.left_eye_naked - baseline.left_eye_naked
        effects['left_vision_effect'] = (
            "上升" if left_vision_change > 0.1 else
            "下降" if left_vision_change < -0.1 else "维持"
        )
    
    if baseline.right_eye_naked and latest.right_eye_naked:
        right_vision_change = latest.right_eye_naked - baseline.right_eye_naked
        effects['right_vision_effect'] = (
            "上升" if right_vision_change > 0.1 else
            "下降" if right_vision_change < -0.1 else "维持"
        )
    
    if baseline.left_se and latest.left_se:
        left_se_change = latest.left_se - baseline.left_se
        effects['left_se_effect'] = (
            "向好发展" if left_se_change > 0.25 else
            "向差发展" if left_se_change < -0.25 else "维持"
        )
    
    if baseline.right_se and latest.right_se:
        right_se_change = latest.right_se - baseline.right_se
        effects['right_se_effect'] = (
            "向好发展" if right_se_change > 0.25 else
            "向差发展" if right_se_change < -0.25 else "维持"
        )
    
    return effects

def recalculate_student(student_id):
    """重新计算学生的所有视力记录"""
    from backend.models.vision import VisionRecord
    from backend.infrastructure.database import db
    
    try:
        # 获取该学生的所有视力记录
        vision_records = VisionRecord.query.filter_by(student_id=student_id).all()
        if not vision_records:
            return {"success": False, "message": "未找到该学生的视力记录"}
        
        updated_count = 0
        for record in vision_records:
            result = calculate_vision_metrics(record)
            if result:
                updated_count += 1
        
        db.session.commit()
        
        return {
            "success": True,
            "message": f"成功重新计算 {updated_count} 条视力记录",
            "updated_count": updated_count
        }
    except Exception as e:
        db.session.rollback()
        return {"success": False, "message": f"重新计算失败: {e}"}